Skip to content

Method: toObject(RDFNode, Class)

1: /**
2: * Copyright (C) 2022 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.ontodriver.jena.query;
16:
17:
18: import cz.cvut.kbss.jopa.datatype.DatatypeTransformer;
19: import cz.cvut.kbss.ontodriver.exception.VariableNotBoundException;
20: import cz.cvut.kbss.ontodriver.jena.exception.JenaDriverException;
21: import cz.cvut.kbss.ontodriver.jena.util.JenaUtils;
22: import org.apache.jena.query.QueryExecution;
23: import org.apache.jena.query.QuerySolution;
24: import org.apache.jena.query.ResultSet;
25: import org.apache.jena.rdf.model.Literal;
26: import org.apache.jena.rdf.model.RDFNode;
27:
28: import java.net.URI;
29: import java.util.Objects;
30:
31: public class SelectResultSet extends AbstractResultSet {
32:
33: private final QueryExecution execution;
34: private final ResultSet jenaResult;
35: private QuerySolution current;
36:
37: public SelectResultSet(QueryExecution execution, ResultSet jenaResult) {
38: this.execution = execution;
39: this.jenaResult = jenaResult;
40: }
41:
42: @Override
43: public int findColumn(String variableName) {
44: ensureOpen();
45: return jenaResult.getResultVars().indexOf(variableName);
46: }
47:
48: @Override
49: public int getColumnCount() {
50: ensureOpen();
51: return jenaResult.getResultVars().size();
52: }
53:
54: @Override
55: public boolean isBound(int variableIndex) {
56: ensureState();
57: return variableIndex >= 0 && variableIndex < jenaResult.getResultVars().size() && current
58: .get(getVariableAt(variableIndex)) != null;
59: }
60:
61: @Override
62: public boolean isBound(String variableName) {
63: ensureState();
64: return jenaResult.getResultVars().contains(variableName) && current.get(variableName) != null;
65: }
66:
67: @Override
68: public boolean getBoolean(int variableIndex) throws JenaDriverException {
69: ensureState();
70: return getBoolean(getVariableAt(variableIndex));
71: }
72:
73: @Override
74: public boolean getBoolean(String variableName) throws JenaDriverException {
75: ensureState();
76: ensureVariableExists(variableName);
77: return getLiteral(variableName).getBoolean();
78: }
79:
80: private Literal getLiteral(String varName) throws JenaDriverException {
81: Objects.requireNonNull(varName);
82: assert current != null;
83: final RDFNode value = getCurrent(varName);
84: if (!value.isLiteral()) {
85: throw new JenaDriverException("Expected value " + value + " to be a literal.");
86: }
87: return current.get(varName).asLiteral();
88: }
89:
90: private RDFNode getCurrent(String varName) {
91: final RDFNode value = current.get(varName);
92: if (value == null) {
93: throw new VariableNotBoundException("Variable " + varName + " is not bound in the current result row.");
94: }
95: return value;
96: }
97:
98: @Override
99: public byte getByte(int variableIndex) throws JenaDriverException {
100: ensureState();
101: return getLiteral(getVariableAt(variableIndex)).getByte();
102: }
103:
104: @Override
105: public byte getByte(String variableName) throws JenaDriverException {
106: ensureState();
107: ensureVariableExists(variableName);
108: return getLiteral(variableName).getByte();
109: }
110:
111: @Override
112: public double getDouble(int variableIndex) throws JenaDriverException {
113: ensureState();
114: return getLiteral(getVariableAt(variableIndex)).getDouble();
115: }
116:
117: @Override
118: public double getDouble(String variableName) throws JenaDriverException {
119: ensureState();
120: ensureVariableExists(variableName);
121: return getLiteral(variableName).getDouble();
122: }
123:
124: @Override
125: public float getFloat(int variableIndex) throws JenaDriverException {
126: ensureState();
127: return getLiteral(getVariableAt(variableIndex)).getFloat();
128: }
129:
130: @Override
131: public float getFloat(String variableName) throws JenaDriverException {
132: ensureState();
133: ensureVariableExists(variableName);
134: return getLiteral(variableName).getFloat();
135: }
136:
137: @Override
138: public int getInt(int variableIndex) throws JenaDriverException {
139: ensureState();
140: return getLiteral(getVariableAt(variableIndex)).getInt();
141: }
142:
143: @Override
144: public int getInt(String variableName) throws JenaDriverException {
145: ensureState();
146: ensureVariableExists(variableName);
147: return getLiteral(variableName).getInt();
148: }
149:
150: @Override
151: public long getLong(int variableIndex) throws JenaDriverException {
152: ensureState();
153: return getLiteral(getVariableAt(variableIndex)).getLong();
154: }
155:
156: @Override
157: public long getLong(String variableName) throws JenaDriverException {
158: ensureState();
159: ensureVariableExists(variableName);
160: return getLiteral(variableName).getLong();
161: }
162:
163: @Override
164: public Object getObject(int variableIndex) {
165: ensureState();
166: assert current != null;
167: return toObject(getCurrent(getVariableAt(variableIndex)));
168: }
169:
170: private static Object toObject(RDFNode value) {
171: assert value != null;
172: if (value.isLiteral()) {
173: return JenaUtils.literalToValue(value.asLiteral());
174: } else {
175: assert value.isResource();
176: if (value.isURIResource()) {
177: return URI.create(value.asResource().getURI());
178: } else {
179: return value.asResource().getId().getLabelString();
180: }
181: }
182: }
183:
184: @Override
185: public Object getObject(String variableName) {
186: ensureState();
187: ensureVariableExists(variableName);
188: assert current != null;
189: return toObject(getCurrent(Objects.requireNonNull(variableName)));
190: }
191:
192: @Override
193: public <T> T getObject(int variableIndex, Class<T> cls) throws JenaDriverException {
194: ensureState();
195: assert current != null;
196: return toObject(getCurrent(getVariableAt(variableIndex)), cls);
197: }
198:
199: private static <T> T toObject(RDFNode value, Class<T> cls) {
200: Objects.requireNonNull(cls);
201:• if (cls.isAssignableFrom(value.getClass())) {
202: return cls.cast(value);
203: }
204: Object objectValue;
205:• if (value.isLiteral()) {
206: objectValue = JenaUtils.literalToValue(value.asLiteral());
207: } else {
208:• assert value.isResource();
209:• if (value.isURIResource()) {
210: objectValue = URI.create(value.asResource().getURI());
211: } else {
212: objectValue = value.asResource().getId().getLabelString();
213: }
214: }
215: return DatatypeTransformer.transform(objectValue, cls);
216: }
217:
218: @Override
219: public <T> T getObject(String variableName, Class<T> cls) throws JenaDriverException {
220: ensureState();
221: ensureVariableExists(variableName);
222: assert current != null;
223: return toObject(getCurrent(variableName), cls);
224: }
225:
226: @Override
227: public short getShort(int variableIndex) throws JenaDriverException {
228: ensureState();
229: return getLiteral(getVariableAt(variableIndex)).getShort();
230: }
231:
232: @Override
233: public short getShort(String variableName) throws JenaDriverException {
234: ensureState();
235: ensureVariableExists(variableName);
236: return getLiteral(variableName).getShort();
237: }
238:
239: @Override
240: public String getString(int variableIndex) {
241: ensureState();
242: return getString(getVariableAt(variableIndex));
243: }
244:
245: private String getVariableAt(int index) {
246: if (index < 0 || index >= jenaResult.getResultVars().size()) {
247: throw new IllegalArgumentException("Variable index " + index + " is out of bounds.");
248: }
249: return jenaResult.getResultVars().get(index);
250: }
251:
252: @Override
253: public String getString(String variableName) {
254: ensureState();
255: ensureVariableExists(variableName);
256: assert current != null;
257: final RDFNode value = getCurrent(variableName);
258: if (value.isResource()) {
259: return value.isURIResource() ? value.asResource().getURI() : value.asResource().getId().getLabelString();
260: } else {
261: return value.asLiteral().getString();
262: }
263: }
264:
265: private void ensureVariableExists(String name) {
266: assert current != null;
267: if (!current.contains(name)) {
268: throw new IllegalArgumentException("Variable '" + name + "' not found in the result set.");
269: }
270: }
271:
272: @Override
273: public boolean hasNext() {
274: ensureOpen();
275: return jenaResult.hasNext();
276: }
277:
278: @Override
279: public void next() {
280: super.next();
281: this.current = jenaResult.next();
282: }
283:
284: @Override
285: public void close() throws JenaDriverException {
286: try {
287: execution.close();
288: super.close();
289: } catch (RuntimeException e) {
290: throw new JenaDriverException("Unable to close result set.", e);
291: }
292: }
293: }